﻿using UnityEngine;

namespace Yoozoo.Modules.InnerCity
{
    public class WalkAction : ActionBase
    {
        private int moveIndex;
        
        private Vector3 moveFrom;
        private Vector3 moveTo;
        private float totalTime;
        private float curTime;

        public bool IsExecuteMove
        {
            get => true;
        }

        protected override StateAction state
        {
            get => StateAction.Walk;
        }

        public override void Init(CityUnit owner)
        {
            base.Init(owner);
        }

        public override void Enter(object args = null)
        {
            Debug.Log("进入了行走状态");
            this.moveIndex = 0;
            RefreshFromAndTo();
            RefreshMoveTime();
            ChangeDirection();
            if (!this.owner.IsStopMove)
                PlayWalkAni();
        }

        public override void Play()
        {
            if (this.owner.IsStopMove)
                return;
            
            this.curTime += Time.deltaTime;
            var percent = this.curTime / this.totalTime;
            if (percent > 1)
                percent = 1;

            this.owner.SetPosition(Vector3.Lerp(this.moveFrom, this.moveTo, percent));
            if (percent < 1)
                return;
            
            OnStageArrive();
        }

        public override void Exit()
        {
            Debug.Log("退出了行走状态");
            this.owner.SharePosToLua();
        }

        protected virtual void PlayWalkAni()
        {
            this.owner.PlayWalkAni();
        }

        protected virtual void OnArrive()
        {
            if (this.owner.MoveEndAction != StateAction.None)
                this.owner.ExecuteMoveEndAction();
            else
                this.owner.ChangeState(StateAction.Idle);
        }

        private void OnStageArrive()
        {
            this.moveIndex++;
            if (this.moveIndex >= this.owner.MoveWayPoints.Count)
            {
                // 表示行动完成
                this.moveIndex = -1;
                OnArrive();
                return;;
            }
            
            RefreshFromAndTo();
            RefreshMoveTime();
            ChangeDirection();
        }

        private void RefreshFromAndTo()
        {
            var to = this.owner.MoveWayPoints[this.moveIndex];
            this.moveTo.x = to.x;
            this.moveTo.z = to.z;

            var index = this.moveIndex - 1;
            var from = index < 0 ? this.owner.Position : this.owner.MoveWayPoints[index];
            this.moveFrom.x = from.x;
            this.moveFrom.z = from.z;            
        }

        private void RefreshMoveTime()
        {
            var dis = Vector3.Distance(this.moveTo, this.moveFrom);
            this.totalTime = dis / CityUnitMgr.unitWalkSpeed;
            this.curTime = 0;
        }

        private void ChangeDirection()
        {
            var vec = this.owner.MoveWayPoints[this.moveIndex];
            if (vec.y == 0)
                return;

            var x = vec.y / 1000;
            var z = vec.y % 1000;
            if (x > 100)
                x = -(x - 100);

            if (z > 100)
                z = -(z - 100);
            
            var r = this.owner.Rotation;
            r.x = x;
            r.z = z;
            this.owner.SetRotation(r);
        }
    }
}